<template>
  <div class="v-table">
    <div class="v-table-body">
      <v-table-header/>
      <v-table-tr v-for="(d,i) in voucherDetailList"
                  :subjectList="subjectList"
                  :subjectMap="subjectMap"
                  :rowIndex="i"
                  :voucherDetail="d"/>
      <v-table-tr-total :detailList="voucherDetailList"/>
    </div>
  </div>
</template>

<script setup>
import VTableHeader from "@components/common/VoucherTable/VTableHeader.vue";
import VTableTr from "@components/common/VoucherTable/VTableTr.vue";
import {defineProps, nextTick, onMounted, provide, ref, watch} from "vue";
import {useStore} from "vuex";
import {ArrToObj} from "@common/utils";
import VTableTrTotal from "@components/common/VoucherTable/VTableTrTotal.vue";
import {add, floor, pick, round, subtract} from "xe-utils";
import RelationVoucher from "@js/api/RelationVoucher";
import RelationSubject from "@js/api/RelationSubject";
// import EventBus from "@/js/common/EventBus";

const props = defineProps(['voucherDetails', 'isEdit', 'readonly', 'carryover']);
const emits = defineEmits(['update']);
const store = useStore();

const newEmptyRow = () => {
  return {
    summary: '',
    debitAmount: null,
    debitAmountFor: 0,
    originalCreditAmount: 0,
    originalDebitAmount: 0,
    creditAmount: null,
    creditAmountFor: 0,
    subject: null,
    subjectId: null,
    auxiliary: [],
    currencyId: null,
    num: 0,
    debitNum: 0,
    creditNum: 0,
    price: 0,
    exchangeRate: 0,
  };
}

const rowColRefs = {};
const subjectList = ref([]);
const subjectMap = ref({});
const subjectOriginalBalance = ref({});
const subjectBalance = ref({});
const voucherDetailList = ref([newEmptyRow(), newEmptyRow(), newEmptyRow(), newEmptyRow()]);

const defaultList = () => {
  return [newEmptyRow(), newEmptyRow(), newEmptyRow(), newEmptyRow()];
}

const newRow = (rowIndex) => {
  voucherDetailList.value.splice(rowIndex + 1, 0, newEmptyRow())
}

const loadSubject = () => {
  RelationSubject.loadSubject().then(({data}) => {
    subjectList.value = data;

    subjectMap.value = ArrToObj(data, val => val.id)
    voucherDetailList.value.forEach(vd => {
      if (vd.id && !vd.subject) {
        vd.subject = subjectMap.value[vd.id];
      }
    })
  })
}

loadSubject();

const clearAll = () => {
  voucherDetailList.value = defaultList();
}

const rmRow = (rowIndex) => {
  if (voucherDetailList.value.length < 5) {
    voucherDetailList.value.splice(rowIndex, 1, newEmptyRow())
  } else {
    voucherDetailList.value.splice(rowIndex, 1);
  }
}

watch(voucherDetailList, (val) => {
  emits('update', val.filter(val => {
    return (val.debitAmount != null || val.creditAmount != null);
  }).map(value => {
    if (value.subject) {
      value.subjectId = value.subject.id;
    }
    return pick(value, Object.keys(value).filter(val => val !== 'subject'));
  }));
}, {deep: true})

watch(() => props.voucherDetails, (val) => {
  let list = defaultList();
  (val || []).forEach((row, index) => {
    list[index] = row;
  })
  voucherDetailList.value = list;
})

onMounted(() => {
  let list = voucherDetailList.value;
  (props.voucherDetails || []).forEach((row, index) => {
    voucherDetailList.value[index] = row;
  })
  voucherDetailList.value = list;
})

// EventBus.on("reloadSubject", loadSubject)

/**
 * 获取最近一行的摘要
 */
provide("getNearSummary", (rowIndex) => {
  for (let i = rowIndex - 1; i >= 0; i--) {
    const summary = voucherDetailList.value[i].summary
    if (summary) {
      return summary;
    }
  }
  return "";
})

/**
 * 获取明细列表
 */
provide('getDetailList', () => {
  return voucherDetailList.value;
})

/**
 * 更新明细字段
 */
provide('updateFiled', (rowIndex, col, val) => {
  if (val) {
    if (col === 'creditAmount') {
      voucherDetailList.value[rowIndex]['debitAmount'] = null;
    } else if (col === 'debitAmount') {
      voucherDetailList.value[rowIndex]['creditAmount'] = null;
    }
  }
  voucherDetailList.value[rowIndex][col] = val;
})

/**
 * 跳转到下一个字段
 */
provide('next', (rowIndex, nextCol) => {
  const detail = voucherDetailList.value;
  if (rowColRefs[rowIndex]) {
    rowColRefs[rowIndex][nextCol].doEdit();
  } else {
    detail.push(newEmptyRow())
    nextTick(() => {
      rowColRefs[rowIndex][nextCol].doEdit();
    })
  }

  if (nextCol === 'summary') {
    //下一行自动平衡
    setTimeout(() => {
      if (detail[rowIndex] && !(detail[rowIndex].debitAmount || detail[rowIndex].creditAmount)) {
        const totalDebit = detail.reduce((total, row) => add(total, (row.debitAmount || 0)), 0)
        const totalCredit = detail.reduce((total, row) => add(total, (row.creditAmount || 0)), 0)
        if (totalDebit !== totalCredit) {
          if (totalDebit > totalCredit) {
            detail[rowIndex].creditAmount = floor(subtract(totalDebit, totalCredit), 2);
          } else {
            detail[rowIndex].debitAmount = floor(subtract(totalCredit, totalDebit), 2);
          }
        }
      }
    }, 200)
  }
})

provide('carryover', props.carryover);

/**
 * 每个组件的引用
 */
provide('pushColInstance', (rowIndex, colRef) => {
  rowColRefs[rowIndex] = colRef;
})

/**
 * 等于号平衡
 */
provide('autoEqAmount', (rowIndex, field) => {
  const detail = voucherDetailList.value.filter((value, index) => index !== rowIndex);
  const totalDebit = detail.reduce((total, row) => add(total, (row.debitAmount || 0)), 0)
  const totalCredit = detail.reduce((total, row) => add(total, (row.creditAmount || 0)), 0)
  //置空自己
  if (field === 'debitAmount') {
    voucherDetailList.value[rowIndex]['creditAmount'] = null;
    voucherDetailList.value[rowIndex][field] = floor(subtract(totalCredit, totalDebit), 2);
  } else {
    voucherDetailList.value[rowIndex]['debitAmount'] = null;
    voucherDetailList.value[rowIndex][field] = floor(subtract(totalDebit, totalCredit), 2);
  }
})

const updateSubjectBalance = (subject) => {
  //合计当前所有列
  const totalAmount = voucherDetailList.value.filter(val => val.subjectId === subject.id).reduce((total, item) => {
    return {
      debitAmount: subtract(add(total.debitAmount, item.debitAmount || 0), item.originalDebitAmount),
      creditAmount: subtract(add(total.creditAmount, item.creditAmount || 0), item.originalCreditAmount)
    };
  }, {debitAmount: 0, creditAmount: 0});
  let orgVal = 0;
  switch (subject.balanceDirection) {
    case '借':
      orgVal = subjectOriginalBalance.value[subject.id] + totalAmount.debitAmount - totalAmount.creditAmount;
      break;
    case '贷':
      orgVal = subjectOriginalBalance.value[subject.id] + totalAmount.creditAmount - totalAmount.debitAmount;
      break;
  }
  subjectBalance.value[subject.id] = round(orgVal, 2);
}

/**
 * 加载科目余额
 */
provide('loadSubjectBalance', (subject, currencyId, acDetails) => {
  // if (!subjectOriginalBalance.value[subject.id]) {
  //   setting.subject.balance({subjectId: subject.id, currencyId, acDetails}).then(({data}) => {
  //     subjectBalance.value = Object.assign({}, subjectBalance.value, {[subject.id]: data});
  //     subjectOriginalBalance.value = Object.assign({}, subjectOriginalBalance.value, {[subject.id]: data});
  //     updateSubjectBalance(subject);
  //   })
  // } else {
  //   updateSubjectBalance(subject);
  // }
})


/**
 * 更新科目余额
 */
provide('updateSubjectBalance', updateSubjectBalance)
provide('subjectBalance', subjectBalance);
provide('newRow', newRow)
provide('rmRow', rmRow)
provide('loadSubject', loadSubject)
provide('voucherDetailList', voucherDetailList)

defineExpose({
  voucherDetailList,
  clearAll
})
</script>

<style scoped lang="less">
.v-table {
  background: @white-color;
  font-size: 12px;
  width: 1000px;
  padding: 10px 10px;

  &-body {
    border: @border;
  }
}
</style>
